<?php

namespace App\Amqp\Consumer;

use App\Cache\RedisKey;
use App\Cache\UserScoreCache;
use App\Constants\RecommendedGradeCode;
use App\Model\PayOrder;
use App\Model\UserScore;
use App\Model\UserScoreLog;
use App\Model\UserTypeRule;
use App\Model\VideoCall;
use App\Service\ServiceTrait\GetUserInfoTrait;
use Hyperf\Amqp\Annotation\Consumer;
use Hyperf\Amqp\Message\ConsumerMessage;
use Hyperf\Amqp\Message\Type;
use Hyperf\Amqp\Result;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Model;
use PhpAmqpLib\Message\AMQPMessage;

/**
 * @Consumer(exchange="UserScore", routingKey="UserScore", queue="UserScore.send", name ="UpdateUserScoreConsumer", nums=5)
 */
class UpdateUserScoreConsumer extends ConsumerMessage
{
    use GetUserInfoTrait;

    /**
     * @var string
     */
    protected $type = Type::DIRECT;

    /**
     * 用户id
     * @var int
     */
    private $actionUserId;

    /**
     * 用户信息
     * @var false|Builder|Model|mixed|object|null
     */
    private $profileInfo;

    /**
     * 获取用户等级
     * @var array
     */
    private $userGrade = [];

    public function consumeMessage($data, AMQPMessage $message): string
    {
        //数据不存在
        if (!$data['user_id']) {
            log_error('UpdateUserScoreConsumer:error:NoUserId:data:' . json_encode($data));
            return Result::ACK;
        }

        $this->actionUserId = $data['user_id'];
        $this->profileInfo = $this->getUserInfo($this->actionUserId);

        //如果有老的并且已经固定
        $scoreInfo = UserScore::getInfoByUserId($this->actionUserId);
        if (!empty($scoreInfo) && $scoreInfo->type == RecommendedGradeCode::FIX_OPERATE){
            log_info('UpdateUserScoreConsumer:info:data:' . json_encode($data).":ps:The user is locked without operation");
            return Result::ACK;
        }

        //性别不对 踢出
        if (!in_array($this->profileInfo->gender,[0,1])){
            log_info('UpdateUserScoreConsumer:info:data:' . json_encode($data).":ps:The user does not have a complete profile");
            return Result::ACK;
        }

        switch ($this->profileInfo->gender)
        {
            case 0:
                $typeId = $this->female();
                break;
            case 1:
                $typeId = $this->male();
                break;
        }

        //获取不到等级 出现等级断档
        if (empty($typeId)){
            log_info('UpdateUserScoreConsumer:info:data:' . json_encode($data).':gender:'.$this->profileInfo->gender.
                ':gradeInfo:'.json_encode($this->userGrade).":ps:A level break occurs 1");
            return Result::ACK;
        }

        $gradeCode = RecommendedGradeCode::GRADE_ARRAY[$typeId];
        if (empty($gradeCode)){
            log_info('UpdateUserScoreConsumer:info:data:' . json_encode($data).':gender:'.$this->profileInfo->gender.
                ':gradeInfo:'.json_encode($this->userGrade).":ps:A level break occurs 2");
            return Result::ACK;
        }


        //如果有老的分数排行删除掉
        if (!empty($scoreInfo) && $scoreInfo->type_id != $typeId){
            $scoreGradeCode = RecommendedGradeCode::GRADE_ARRAY[$scoreInfo['type_id']];
            $scoreKey = RedisKey::todayUserGradeList($scoreGradeCode);
            UserScoreCache::delGradeUser($scoreKey,$this->actionUserId);
        }

        //添加等级用户
        $key = RedisKey::todayUserGradeList($gradeCode);
        UserScoreCache::addGradeUser($key,$this->actionUserId);

        //更新等级记录
        UserScore::updateOrCreate([
            'user_id' => $this->actionUserId,
            'type' => RecommendedGradeCode::AUTO_OPERATE
        ],[
            'type_id' => $typeId,
        ]);

        //添加等级更改日志
        UserScoreLog::create([
            'user_id' => $this->actionUserId,
            'type_id' => $typeId,
            'type' => RecommendedGradeCode::AUTO_OPERATE
        ]);

        return Result::ACK;
    }

    /**
     * 获取女士的等级
     * @return int|mixed
     */
    private function female()
    {
        $this->userGrade = $userGrade = UserTypeRule::getUserGradeByGender(0);

        //视频接听时间
        $videoAnswerTime = VideoCall::getCallNum('total_call_minutes', '', '', 0, 0, $this->actionUserId);
        //视频呼叫时间
        $videoCallTime = VideoCall::getCallNum('total_call_minutes', '', '', 0, $this->actionUserId);
//        VoiceCall::getCallNum()

        $totalCallMinutes = $videoAnswerTime + $videoCallTime;

        $typeId = 0;
        foreach ($userGrade as $one){
            if (empty($one['call_max']) && empty($one['call_min']))
            {
                continue;
            }

            if (empty($one['call_max']) && $totalCallMinutes >= $one['call_min'])
            {
                return $one['type_id'];
            }

            if (empty($one['call_min']) && $totalCallMinutes < $one['call_max'])
            {
                return $one['type_id'];
            }

            if ($totalCallMinutes >= $one['call_min'] && $totalCallMinutes < $one['call_max'])
            {
                return $one['type_id'];
            }
        }

        return $typeId;
    }

    /**
     * 获取男士的等级
     * @return int|mixed
     */
    private function male()
    {
        $this->userGrade = $userGrade = UserTypeRule::getUserGradeByGender(1);

        $regCycle = $userGrade[0]['reg_cycle'] ?? RecommendedGradeCode::MALE_DEFAULT_DAY;

        if ($this->profileInfo->created_at > date("Y-m-d H:i:s", strtotime('-'.$regCycle.' day'))){
            return RecommendedGradeCode::MALE_TOURIST;
        }

        array_pop($userGrade);

        $payPoints = PayOrder::getSuccessTotal($this->actionUserId);
        $payTotal = bcdiv($payPoints, 100, 2);

        $typeId = 0;
        foreach ($userGrade as $one){
            if (empty($one['recharge_max']) && empty($one['recharge_min'])){
                continue;
            }

            if (empty($one['recharge_max']) && $payTotal >= $one['recharge_min']){
                return $one['type_id'];
            }

            if (empty($one['recharge_min']) && $payTotal < $one['recharge_max'])
            {
                return $one['type_id'];
            }

            if ($payTotal >= $one['recharge_min'] && $payTotal < $one['recharge_max']){
                return $one['type_id'];
            }
        }

        return $typeId;
    }
}